package com.tutor.lzm.http;

import android.text.TextUtils;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.LogUtil;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.tutor.lzm.AppSession;
import com.tutor.lzm.app.CommonValue;
import com.tutor.syslib.Logs;
import com.tutor.syslib.util.JsonParse;

import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;


/**
 * Created by Administrator on 2015/11/23 0023.
 */
public class HttpClient {
    /**
     * @param request
     * @param onSuccessListener
     * @param onFailListener
     */
    public static void post(final BaseRequest request, final onSuccessListener onSuccessListener, final onFailListener onFailListener) {
        post(request, onSuccessListener, null, onFailListener);
    }

    /**
     * @param request
     * @param onSuccessStringListener
     * @param onFailListener
     */
    public static void post(final BaseRequest request, final onSuccessStringListener onSuccessStringListener, final onFailListener onFailListener) {
        post(request, null, onSuccessStringListener, onFailListener);
    }

    /**
     * @param request
     * @param onSuccessListener
     * @param onSuccessStringListener
     * @param onFailListener
     */
    public static void post(final BaseRequest request, final onSuccessListener onSuccessListener, final onSuccessStringListener onSuccessStringListener, final onFailListener onFailListener) {
        RequestParams params = new RequestParams();
        String json = JsonParse.getInstance().getJsonFromObject(request);

        if (!(request instanceof Collection) && !(request instanceof Map) && !request.isMap()) {
            json = jsonValueToArray(json);
        } else {
        }

        try {
            JsonNode bodyNode = JsonParse.getInstance().JsonMapper().readTree(json);
            StringWriter sw = new StringWriter();
            JsonGenerator generator = JsonParse.getInstance().getJsonFactory().createGenerator(sw);
            if (!(request.getServiceId() == null && request.getMethod() == null)) {
                generator.writeStartObject();
                generator.writeStringField("serviceId", request.getServiceId());
                generator.writeStringField("method", request.getMethod());
                generator.writeFieldName("body");
                generator.writeTree(bodyNode);
                generator.writeEndObject();
            } else {
                generator.writeObject(request);
            }

            generator.close();
            json = sw.toString();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            params.setBodyEntity(new StringEntity(json, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        HttpUtils http = new HttpUtils();
        params.addHeader("Content-Type", "application/json");
        params.addHeader("charset", HTTP.UTF_8);
        params.addHeader("X-Access-Token", AppSession.tokenId);
        params.addHeader("X-Client-Id", AppSession.clientId);
        String url = CommonValue.HostServerUrl;
        if (!TextUtils.isEmpty(request.getUrl())) {
            url = request.getUrl();
        }

        http.send(HttpRequest.HttpMethod.POST,
                url,
                params,
                new RequestCallBack<String>() {

                    @Override
                    public void onStart() {

                    }

                    @Override
                    public void onLoading(long total, long current, boolean isUploading) {

                    }

                    @Override
                    public void onSuccess(ResponseInfo<String> responseInfo) {
                        LogUtil.w("Receive response for method:" + request.getMethod() + ", serviceId:" + request.getServiceId() + " \n" + responseInfo.result);
                        int resultCode = 0;
                        String body = "";
                        BaseResponse response = null;
                        try {
                            JSONObject jsonObject = new JSONObject(responseInfo.result);
                            resultCode = jsonObject.optInt("code");
                            body = jsonObject.optString("body");
                            if (request.getResponseClass() != null) {
                                response = JsonParse.getInstance().getObjectFromJson(body, request.getResponseClass());
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        if (resultCode == 200) {
                            if (response == null && request.getResponseClass() != null) {
                                try {
                                    response = request.getResponseClass().newInstance();
                                } catch (InstantiationException e) {
                                    e.printStackTrace();
                                } catch (IllegalAccessException e) {
                                    e.printStackTrace();
                                }
                            }
                            if (onSuccessListener != null) {
                                onSuccessListener.onSuccess(response);
                            }
                            if (onSuccessStringListener != null) {
                                onSuccessStringListener.onSuccess(body);
                            }
                        } else {
                            if (onFailListener != null) {
                                String msg = "";
                                try {
                                    JSONObject object = new JSONObject(responseInfo.result);
                                    msg = object.optString("msg");
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                                onFailListener.onFail(resultCode, msg);
                            }
                        }
                    }

                    @Override
                    public void onFailure(HttpException error, String msg) {
                        LogUtil.d("Receive error response for method:" + request.getMethod() + ", serviceId:" + request.getServiceId());
                        LogUtil.d("onFailure:" + error.getExceptionCode() + " msg :" + msg);
//                        SysException.processHttpException(error.getExceptionCode(), msg);
                        if (onFailListener != null) {
                            onFailListener.onFail(error.getExceptionCode(), msg);
                        }
                    }
                });
    }

    /**
     * @param request
     * @param onSuccessListener
     * @param onFailListener
     */
    public static void get(final BaseRequest request, final onSuccessListener onSuccessListener, final onFailListener onFailListener) {
        RequestParams params = new RequestParams();

        HttpUtils http = new HttpUtils();
        params.addHeader("Content-Type", "application/json");
        params.addHeader("charset", HTTP.UTF_8);
        params.addHeader("X-Access-Token", AppSession.tokenId);
        String url = request.getUrl();
        if (TextUtils.isEmpty(url)) {
            throw new IllegalArgumentException("url 为空");
        }
        LogUtil.i("get : conn..." + url);
        http.send(HttpRequest.HttpMethod.GET,
                url,
                params,
                new RequestCallBack<String>() {

                    @Override
                    public void onStart() {

                    }

                    @Override
                    public void onLoading(long total, long current, boolean isUploading) {

                    }

                    @Override
                    public void onSuccess(ResponseInfo<String> responseInfo) {
                        LogUtil.i("Receive response: get : " + request.getUrl() + responseInfo.result);
                        BaseResponse response = null;

                        if (request.getResponseClass() != null) {
                            response = JsonParse.getInstance().getObjectFromJson(responseInfo.result.trim(), request
                                    .getResponseClass
                                            ());

                        }

                        if (response != null) {
                            if (onSuccessListener != null) {
                                onSuccessListener.onSuccess(response);
                            }
                        } else {
                            if (onFailListener != null) {
                                onFailListener.onFail(0, responseInfo.result);
                            }
                        }


                    }

                    @Override
                    public void onFailure(HttpException error, String msg) {
                        LogUtil.d("onFailure:" + error.getExceptionCode() + " msg :" + msg);
//                        SysException.processHttpException(error.getExceptionCode(), msg);
                        if (onFailListener != null) {
                            onFailListener.onFail(error.getExceptionCode(), msg);
                        }
                    }
                });
    }

    public interface onSuccessListener {
        void onSuccess(BaseResponse response);
    }

    public interface onSuccessStringListener {
        void onSuccess(String response);
    }

    public interface onFailListener {
        void onFail(int code, String msg);
    }

    /**
     * @param request
     * @return
     */
    private static String jsonValueToArray(String request) {
        JSONArray jsonArray = new JSONArray();
        try {
            JSONObject jsonObject = new JSONObject(request);
            jsonArray.put(0, jsonObject);
            return jsonArray.toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "";
//        try {
//            JsonNode rootNode = JsonParse.getInstance().JsonMapper().readTree(request);
//            Iterator<String> keys = rootNode.fieldNames();
//            JSONArray jsonArray = new JSONArray();
//            while (keys.hasNext()) {
//                String fieldName = keys.next();
//                JsonNode node = rootNode.path(fieldName);
//                if (node.isNumber()) {
//                    jsonArray.put(node.numberValue());
//                }
//                else if(node.isTextual()){
//                    jsonArray.put(node.asText());//toString()有双引号，textvalue()有可能是null
//                }
//                else if(node.isBoolean()){
//                    jsonArray.put(node.booleanValue());
//                }
//                else if (node.isArray())
//                {
//                    jsonArray.put(new JSONArray(node.toString()));
//                }
//                else
//                {
//                    try {
//                        JSONObject json = new JSONObject(JsonParse.getInstance().getJsonFromObject(node));
//                        jsonArray.put(json);
//                    } catch (JSONException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//            return jsonArray.toString();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } catch (JSONException e) {
//            e.printStackTrace();
//        }
//
//        return "";
    }
}
